#include <stdio.h>
#include "esp_log.h"
#include "sr.h"
#include "driver/gpio.h"
#include "nvs_flash.h"
#include "xl9555.h"
#include "nocodec_audio.h"
#include "mp3dec.h"
#include "lvgl.h"
#include "lv_port.h"
#include "lv_demos.h"
#include "st7789_i80.h"
#include "gui_guider.h"
#include "custom.h"
#include "events_init.h"
#include "light.h"
#include "ap_wifi.h"
#include "audio_player.h"
#include "esp_spiffs.h"
#include <time.h>
#include <sys/time.h>
#include "esp_sntp.h"

#define TAG     "main"

#define AUDIO_PATH_HEAD     "/audio"

lv_ui guider_ui;

#define LCD_RST_IO           IO1_3
#define LCD_BL_IO            IO1_2
#define TP_RST_IO            IO1_0
#define SPK_EN_IO            IO0_0

#define XL9555_SDA  GPIO_NUM_10
#define XL9555_SCL  GPIO_NUM_11

void i2c_and_xl9555_init(void)
{
    xl9555_init(XL9555_SDA,XL9555_SCL,GPIO_NUM_NC,NULL);
    xl9555_ioconfig((~(LCD_RST_IO | LCD_BL_IO | TP_RST_IO | SPK_EN_IO))&0xFFFF);
}

void audio_start_cb(int state)
{
    esp_sr_enable(false);
}

void audio_finish_cb(int state)
{
    esp_sr_enable(true);
}

void mulit_command_handle(int index)
{
    ESP_LOGI(TAG,"command detected:%d",index);
    static uint8_t brightness = 0;
    switch(index)
    {
        case 1:     //进入氛围模式
            light_start_atmosphere();
            audio_player_play(AUDIO_PATH_HEAD"/atmosphere.wav",audio_write,audio_start_cb,audio_finish_cb);
            break;
        case 2:     //亮度已调高
            brightness += 20;
            if(brightness > 100)
                brightness = 100;
            for(int i = 0;i < 3;i++)
            {
                light_ws2812_set_brightness(i,brightness);
            }
            audio_player_play(AUDIO_PATH_HEAD"/up_brightness.wav",audio_write,audio_start_cb,audio_finish_cb);
            break;
        case 3:     //亮度已降低
            if(brightness < 20)
                brightness = 0;
            else
                brightness -= 20;
            for(int i = 0;i < 3;i++)
            {
                light_ws2812_set_brightness(i,brightness);
            }
            audio_player_play(AUDIO_PATH_HEAD"/down_brightness.wav",audio_write,audio_start_cb,audio_finish_cb);
            break;
        case 4:     //关闭灯光
            light_stop_atmosphere();
            vTaskDelay(pdMS_TO_TICKS(50));
            for(int i = 0;i < 3;i++)
            {
                light_ws2812_on(i,0,0,0);
            }
            light_led_on(0);
            audio_player_play(AUDIO_PATH_HEAD"/turnoff.wav",audio_write,audio_start_cb,audio_finish_cb);
            break;
        case 5: //开始配网
            ap_wifi_apcfg(true);
            wifi_display_style(&guider_ui,LV_WIFI_STYLE_CONFIG);
            audio_player_play(AUDIO_PATH_HEAD"/netconfig.wav",audio_write,audio_start_cb,audio_finish_cb);
            break;
        default:break;
    }
}

void wakeup_handle(bool wakeup)
{
    if(wakeup)
    {
        ESP_LOGI(TAG,"Wakeup detected");
        audio_player_play(AUDIO_PATH_HEAD"/wakeup.wav",audio_write,audio_start_cb,audio_finish_cb);
    }
    else
    {
        audio_player_play(AUDIO_PATH_HEAD"/exit_wakeup.wav",audio_write,audio_start_cb,audio_finish_cb);
    }
}

/** 语音输入任务
 * @param arg 任务参数
 * @return 无
 */
void feed_Task(void *arg)
{
    int wakeup_feedsize = esp_sr_get_feedsize();
    int16_t *wakeup_buff = malloc(wakeup_feedsize*sizeof(int16_t));
    ESP_LOGI(TAG,"wakeup feedsize:%d",wakeup_feedsize);
    while(1)
    {
        if(esp_sr_is_process())
        {
            audio_read(wakeup_buff,wakeup_feedsize);
            esp_sr_feed(wakeup_buff,wakeup_feedsize);
        }
        vTaskDelay(pdMS_TO_TICKS(20));
    }
    vTaskDelete(NULL);
}

//校时成功后的回调
static void time_sync_notification_cb(struct timeval *tv)
{
    struct tm *tm;
    // 使用localtime将tv_sec转换为本地时间表示的tm结构体
    tm = localtime(&tv->tv_sec);
    set_home_time(&guider_ui,tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
}

//时间同步
static void initialize_sntp(void)
{
    ESP_LOGI(TAG, "Initializing SNTP");
    esp_sntp_setoperatingmode(ESP_SNTP_OPMODE_POLL);
    esp_sntp_setservername(0, "ntp.aliyun.com");
    esp_sntp_setservername(1, "time.asia.apple.com");
    esp_sntp_setservername(2, "pool.ntp.org");
    esp_sntp_set_time_sync_notification_cb(time_sync_notification_cb);
    esp_sntp_init();
}

void  wifi_state_callback(WIFI_STATE state)
{
    if(state == WIFI_STATE_CONNECTED)
    {
        wifi_display_style(&guider_ui,LV_WIFI_STYLE_CONNECTED);
        audio_player_play(AUDIO_PATH_HEAD"/connected.wav",audio_write,audio_start_cb,audio_finish_cb);
        initialize_sntp();
    }
    else
    {
        wifi_display_style(&guider_ui,LV_WIFI_STYLE_DISCONNECTED);
        audio_player_play(AUDIO_PATH_HEAD"/disconnected.wav",audio_write,audio_start_cb,audio_finish_cb);
    }
}

void lvgl_task(void* arg)
{
    st7789_i80_lcd_backlight(true);         //打开背光
    lv_port_init();                 //初始化LVGL
    //lv_demo_widgets();              //初始化控件demo程序
    //lv_demo_stress();
    //vTaskDelay(pdMS_TO_TICKS(200));
    setup_ui(&guider_ui);
    events_init(&guider_ui);
    custom_init(&guider_ui);
    wifi_display_style(&guider_ui,LV_WIFI_STYLE_DISCONNECTED);
    audio_player_play(AUDIO_PATH_HEAD"/welcome.wav",audio_write,audio_start_cb,audio_finish_cb);
    while(1)
    {
        vTaskDelay(1);
        lv_port_lock();
        lv_task_handler();          //LVGL循环处理
        lv_port_unlock();
    }
    vTaskDelete(NULL);
    return;
}


static void load_audio_resource(void)
{
    //定义挂载点
    esp_vfs_spiffs_conf_t conf = {
        .base_path = AUDIO_PATH_HEAD,       //挂载点
        .partition_label = "audio",         //分区名称
        .max_files = 3,                    //最大打开的文件数
        .format_if_mount_failed = false    //挂载失败是否执行格式化
    };
    //挂载spiffs
    ESP_ERROR_CHECK(esp_vfs_spiffs_register(&conf));
}

void app_main(void)
{
    //nvs初始化
    nvs_flash_init();
    //i2s初始化
    init_speaker(GPIO_NUM_46,GPIO_NUM_9,GPIO_NUM_8,16000);
    init_pdm_microphone(GPIO_NUM_42,GPIO_NUM_3,16000);
    //加载音频资源
    load_audio_resource();
    //初始化XL9555
    i2c_and_xl9555_init();
    //灯光初始化
    light_init();
    //喇叭使能
    xl9555_pin_write(SPK_EN_IO,1);
    //语音识别初始化
    ESP_SR_cb_t cbf = 
    {
        .mulit_func = mulit_command_handle,
        .wakeup_func = wakeup_handle,
    };
    esp_sr_init(&cbf);
    esp_sr_add_command(1,"fen wei mo shi");
    esp_sr_add_command(2,"tiao liang deng guang");
    esp_sr_add_command(3,"tiao an deng guang");
    esp_sr_add_command(4,"guan bi deng guang");
    esp_sr_add_command(5,"kai shi pei wang");
    esp_sr_start();
    esp_sr_enable(true);
    //语音输入任务
    xTaskCreatePinnedToCore(feed_Task,"feed",8192,NULL,5,NULL,0);
    //lvgl显示任务
    xTaskCreatePinnedToCore(lvgl_task,"lvgl",8192,NULL,6,NULL,1);
    //初始化wifi
    ap_wifi_init(wifi_state_callback);
    //设置时区
    setenv("TZ", "CST-8", 1);
    tzset();
}
